<template>
  <view class="component-upload-image">
    <!-- 上传按钮 -->
    <view 
      class="upload-btn" 
      @click="chooseImage" 
      :class="{ disabled: disabled || fileList.length >= limit }"
    >
      <uni-icons type="image" size="30"></uni-icons>
      <text>上传图片</text>
    </view>

    <!-- 已上传图片列表 -->
    <view class="image-list">
      <view 
        class="image-item" 
        v-for="(file, index) in fileList" 
        :key="index"
      >
        <!-- 图片预览 -->
        <image 
          class="preview-img" 
          :src="file.url" 
          mode="aspectFill" 
          @click="handlePreview(index)"
        ></image>
        
        <!-- 删除按钮 -->
        <view 
          class="delete-btn" 
          @click.stop="handleDelete(index)"
          :disabled="disabled"
        >
          <uni-icons type="close" size="20"></uni-icons>
        </view>
      </view>
    </view>

    <!-- 上传提示 -->
    <view class="upload-tip" v-if="showTip && !disabled">
      支持格式: {{ fileType.join('/') }}，最大尺寸: {{ fileSize }}MB，最多上传: {{ limit }}张
    </view>

    <!-- 预览弹窗 -->
    <uni-popup v-model="previewVisible" mode="center">
      <view class="preview-container">
        <image 
          :src="previewUrl" 
          mode="widthFix" 
          class="popup-img"
        ></image>
      </view>
    </uni-popup>
  </view>
</template>

<script>
import { uploadFile } from '@/api/file/file.js';
import { getToken } from '@/utils/auth.js';
import { toast } from '@/utils/common.js';

export default {
  name: 'ImageUpload',
  props: {
    modelValue: {
      type: [String, Array],
      default: ''
    },
    uploadAction: {
      type: String,
      default: '/file/upload'
    },
    uploadData: {
      type: Object,
      default: () => ({})
    },
    limit: {
      type: Number,
      default: 5
    },
    fileSize: {
      type: Number,
      default: 5
    },
    fileType: {
      type: Array,
      default: () => ['png', 'jpg', 'jpeg']
    },
    showTip: {
      type: Boolean,
      default: true
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      fileList: [],
      previewVisible: false,
      previewUrl: ''
    };
  },
  computed: {
    baseUrl() {
      const config = require('@/config.js'); 
      return config.baseUrl;
    }
  },
  watch: {
    modelValue: {
      handler(val) {
        if (!val) {
          this.fileList = [];
          return;
        }
        const urls = Array.isArray(val) ? val : val.split(',').filter(url => url);
        this.fileList = urls.map(url => ({ url }));
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    chooseImage() {
      if (this.disabled || this.fileList.length >= this.limit) return;

      uni.chooseImage({
        count: this.limit - this.fileList.length,
        sourceType: ['album', 'camera'],
        success: (res) => {
          this.handleSelectedImages(res.tempFilePaths);
        },
        fail: () => {
          toast('选择图片失败');
        }
      });
    },

    handleSelectedImages(tempFilePaths) {
      tempFilePaths.forEach(tempFilePath => {
        uni.getFileInfo({
          filePath: tempFilePath,
          success: (fileInfo) => {
            if (this.validateFile(fileInfo, tempFilePath)) {
              this.uploadSingleImage(tempFilePath);
            }
          },
          fail: () => {
            toast('获取文件信息失败');
          }
        });
      });
    },

    validateFile(fileInfo, filePath) {
      const ext = filePath.split('.').pop().toLowerCase();
      if (!this.fileType.includes(ext)) {
        toast(`仅支持${this.fileType.join('/')}格式`);
        return false;
      }

      if (fileInfo.size / 1024 / 1024 > this.fileSize) {
        toast(`文件大小不能超过${this.fileSize}MB`);
        return false;
      }

      if (filePath.split('/').pop().includes(',')) {
        toast('文件名不能包含逗号');
        return false;
      }

      return true;
    },

    uploadSingleImage(tempFilePath) {
      uni.showLoading({ title: '上传中...' });
      
      uploadFile(tempFilePath).then((res) => {
        uni.hideLoading();
        if (res.code === 200 && res.data?.url) {
          this.fileList.push({ url: res.data.url });
          this.syncToParent();
          toast('上传成功');
        } else {
          toast(res.msg || '上传失败');
        }
      }).catch(() => {
        uni.hideLoading();
        toast('上传异常');
      });
    },

    handleDelete(index) {
      if (this.disabled) return;
      this.fileList.splice(index, 1);
      this.syncToParent();
    },

    handlePreview(index) {
      this.previewUrl = this.fileList[index].url;
      this.previewVisible = true;
    },

    syncToParent() {
      const urls = this.fileList.map(item => item.url);
      this.$emit('update:modelValue', urls.join(','));
      this.$emit('change', urls);
    }
  }
};
</script>

<style scoped>
.component-upload-image {
  width: 100%;
  box-sizing: border-box;
  padding: 10rpx;
}

.upload-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 160rpx;
  height: 160rpx;
  border: 2rpx dashed #ccc;
  border-radius: 8rpx;
  color: #666;
  margin-bottom: 20rpx;
}

.upload-btn.disabled {
  opacity: 0.6;
  pointer-events: none;
}

.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
  margin-bottom: 20rpx;
}

.image-item {
  position: relative;
  width: 160rpx;
  height: 160rpx;
  border-radius: 8rpx;
  overflow: hidden;
}

.preview-img {
  width: 100%;
  height: 100%;
}

.delete-btn {
  position: absolute;
  top: 0;
  right: 0;
  width: 40rpx;
  height: 40rpx;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-tip {
  font-size: 24rpx;
  color: #999;
  line-height: 1.5;
}

.preview-container {
  padding: 20rpx;
}

.popup-img {
  max-height: 80vh;
}
</style>